Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SM-999] Add Bulk Move to Project Endpoint #66

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

lizard-boy
Copy link

@lizard-boy lizard-boy commented Oct 19, 2024

Type of change

- [ ] Bug fix
- [x] New feature development
- [ ] Tech debt (refactoring, code cleanup, dependency upgrades, etc)
- [ ] Build/deploy pipeline (DevOps)
- [ ] Other

Objective

Add new endpoint for updating the projects of many secrets to the same project.

Clients PR: bitwarden/clients#6665

Code changes

  • bitwarden_license/src/Commercial.Infrastructure.EntityFramework/SecretsManager/Repositories/SecretRepository.cs: This interacts with the virtual table ProjectSecret to avoid making large changes in the code base or to make this update one row at a time. It deletes all current relationships for the given secrets and then creates new relationships for them based on the supplied project ids.
  • src/Api/SecretsManager/Controllers/SecretsController.cs: Controller method for validating that the current user has the permissions to do the specified action.

Before you submit

  • Please check for formatting errors (dotnet format --verify-no-changes) (required)
  • If making database changes - make sure you also update Entity Framework queries and/or migrations
  • Please add unit tests where it makes sense to do so (encouraged but not required)
  • If this change requires a documentation update - notify the documentation team
  • If this change has particular deployment requirements - notify the DevOps team

Greptile Summary

This pull request adds a new endpoint for bulk moving secrets to a project in the Secrets Manager, including necessary authorization, command implementation, and unit tests.

  • Added BulkMoveToProjectAsync method in SecretsController.cs to handle the new bulk move endpoint
  • Implemented MoveSecretsCommand and BulkSecretAuthorizationHandler for executing and authorizing bulk secret operations
  • Created ProjectSecret entity to represent many-to-many relationships between projects and secrets
  • Added new methods AccessToSecretsAsync and MoveSecretsAsync to ISecretRepository interface and implementations
  • Created empty migration files for MySQL, PostgreSQL, and SQLite that need to be properly implemented

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

26 file(s) reviewed, 24 comment(s)
Edit PR Review Bot Settings | Greptile

BulkSecretOperationRequirement requirement,
IReadOnlyList<Secret> resource)
{
var secretsByOrganizationId = resource.GroupBy(s => s.OrganizationId).ToArray();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider using FirstOrDefault() instead of ToArray() for better performance when only checking for a single group.

Comment on lines +65 to +66
var secretAccesses = await _secretRepository.AccessToSecretsAsync(
secrets.Select(s => s.Id).ToArray(), userId, accessClientType);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: This could potentially be a performance bottleneck for large numbers of secrets. Consider implementing a batch operation in the repository.

secrets.Select(s => s.Id).ToArray(), userId, accessClientType);

// If we don't have the write permission
return secretAccesses.All(a => a.Value.Write);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Ensure that secretAccesses contains an entry for every secret, otherwise this check might pass incorrectly.

Comment on lines +354 to +356
await dbContext.ProjectSecrets
.Where(ps => secretIds.Contains(ps.SecretsId))
.ExecuteDeleteAsync();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: This operation deletes all existing project-secret relationships. Ensure this is the intended behavior, as it may have unintended consequences

Guid userId,
AccessClientType accessType)
{
await using var scope = ServiceScopeFactory.CreateAsyncScope();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Use 'using' instead of 'await using' for consistency with other methods

Comment on lines +2188 to +2201
modelBuilder.Entity("Bit.Infrastructure.EntityFramework.SecretsManager.Models.ProjectSecret", b =>
{
b.HasOne("Bit.Infrastructure.EntityFramework.SecretsManager.Models.Project", null)
.WithMany()
.HasForeignKey("ProjectsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();

b.HasOne("Bit.Infrastructure.EntityFramework.SecretsManager.Models.Secret", null)
.WithMany()
.HasForeignKey("SecretsId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Cascade delete behavior for ProjectSecret relationships may cause unintended data loss if not carefully managed

Comment on lines +11 to +14
protected override void Up(MigrationBuilder migrationBuilder)
{

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Up method is empty. Implement table creation, indexes, and foreign keys for ProjectSecret entity.

Comment on lines +17 to +20
protected override void Down(MigrationBuilder migrationBuilder)
{

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Down method is empty. Implement logic to revert changes made in Up method.

Comment on lines +11 to +14
protected override void Up(MigrationBuilder migrationBuilder)
{

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The Up method is empty. It should create the ProjectSecret table with appropriate columns.

Comment on lines +17 to +20
protected override void Down(MigrationBuilder migrationBuilder)
{

}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: The Down method is empty. It should drop the ProjectSecret table to revert the migration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants